package net.sudot.chess.business.controller.web;

import net.sudot.chess.business.controller.websocket.ChatWebSocketServer;
import net.sudot.chess.business.dto.WechatMessageDTO;
import net.sudot.chess.business.model.ChatRecord;
import net.sudot.chess.business.model.Customer;
import net.sudot.chess.business.model.Room;
import net.sudot.chess.business.model.WechatGroup;
import net.sudot.chess.business.service.ChatRecordService;
import net.sudot.chess.business.service.CustomerService;
import net.sudot.chess.business.service.RoomService;
import net.sudot.chess.business.service.WechatGroupService;
import net.sudot.chess.business.wechat.message.PlayTemplateMessage;
import net.sudot.chess.util.WBihuizhiUtils;
import net.sudot.commons.security.CsrfInterceptor;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.text.StringEscapeUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Element;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.annotation.Resource;
import java.util.List;
import java.util.Optional;

/**
 * 微信个人机器人接口
 *
 * @author tangjialin on 2018-11-04.
 */
@Controller
@RequestMapping("/wechat-bot")
public class WechatBotController {
    private final Logger logger = LoggerFactory.getLogger(getClass());
    private final boolean debugEnabled = logger.isDebugEnabled();

    @Resource
    private RoomService roomService;
    @Resource
    private CustomerService customerService;
    @Resource
    private ChatRecordService chatRecordService;
    @Resource
    private WechatGroupService wechatGroupService;
    @Resource
    private PlayTemplateMessage playTemplateMessage;

    /**
     * 收到新信息
     *
     * @param message 收到的信息内容
     */
    @CsrfInterceptor.Ignore
    @PostMapping("/message")
    public ResponseEntity<String> message(@RequestBody WechatMessageDTO message) {
        String groupName = Optional.ofNullable(message.getRoom()).map(WechatMessageDTO.Room::getTopic).orElse("");
        String fromUserName = message.getFromUserName();
        String content = message.getContent();
        if (StringUtils.isEmpty(groupName)) { return ResponseEntity.noContent().build(); }
        logger.info("MessageEvent 收到[{}:{}]的信息\n{}", groupName, fromUserName, content);

        String roomSn = null;
        if (message.getMsgType() == 1) {
            content = StringEscapeUtils.unescapeXml(content);
            Element appMsgElement = Jsoup.parse(content).getElementsByTag("appmsg").first();
            content = appMsgElement.getElementsByTag("url").first().text();
            roomSn = WBihuizhiUtils.getRoomSnByWechatMessage(appMsgElement.getElementsByTag("title").first().text());
        }
        if (!WBihuizhiUtils.validateUrl(content)) {
            return ResponseEntity.noContent().build();
        }
        logger.info("MessageEvent 收到 [{}:{}] 的分享链接: {} {}", groupName, fromUserName, content, content);
        WechatGroup wechatGroup = wechatGroupService.findByName(groupName);
        if (wechatGroup == null) { return ResponseEntity.noContent().build(); }
        Room room = roomService.findPlayingByWechatGroup(wechatGroup.getId());
        if (room == null) { return ResponseEntity.noContent().build(); }
        final String url = content;
        roomSn = Optional.ofNullable(roomSn).orElseGet(() -> WBihuizhiUtils.getRoomSn(WBihuizhiUtils.getHtml(url)));
        room.setUrl(url).setSn(roomSn);
        roomService.update(room);
        Customer customer = customerService.findGameMasterByRoom(room.getId());
        ChatRecord chatRecord = new ChatRecord();
        // 此处net.sudot.chess.config.BaseEntityAuditing获取不到用户信息
        chatRecord.setCreatedBy(customer.getId());
        chatRecord.setLastModifiedBy(customer.getId());
        chatRecord.setRoomId(room.getId());
        chatRecord.setContent("[房号]");
        chatRecordService.save(chatRecord);
        // 发送房间信息更新信息
        ChatWebSocketServer.sendMessageAtRoomUpdate(room.getId(), customer);

        // 发送消息通知玩家开局
        List<Customer> customerList = customerService.findListByRoom(room.getId());
        for (Customer player : customerList) {
            playTemplateMessage.send(player, room);
        }
        return ResponseEntity.noContent().build();
    }
}
